﻿@page "/"
@namespace BlazingPizza.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BlazingPizza</title>
    <base href="~/" />
    <environment include="Development">
        <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
              asp-fallback-href="css/bootstrap/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
              crossorigin="anonymous"
              integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" />
    </environment>
    <link href="css/site.css" rel="stylesheet" />
    <link href="~/leaflet/leaflet.css" rel="stylesheet" />
</head>
<body>
    <app>
        @(await Html.RenderComponentAsync<App>())
    </app>

    <script src="_framework/blazor.server.js"></script>
    <script src="~/leaflet/leaflet.js"></script>

    <script>
        (function () {
            var userInfoComponent;

            window.openLoginPopup = function (component) {
                if (userInfoComponent) {
                    userInfoComponent.dispose();
                }

                userInfoComponent = component;
                var popup = window.open('user/signin?returnUrl=' + encodeURIComponent(location.href), 'loginWindow', 'width=600,height=600');

                // Poll to see if it's closed before completion
                var intervalHandle = setInterval(function () {
                    if (popup.closed) {
                        clearInterval(intervalHandle);
                        onLoginPopupFinished({ isLoggedIn: false });
                    }
                }, 250);
            };

            window.onLoginPopupFinished = function (userState) {
                if (userInfoComponent) {
                    userInfoComponent.invokeMethodAsync('OnSignInStateChanged', userState);
                    userInfoComponent.dispose();
                    userInfoComponent = null;
                }
            };

            var tileUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
            var tileAttribution = 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>';

            // Global export
            window.deliveryMap = {
                showOrUpdate: function (elementId, markers) {
                    var elem = document.getElementById(elementId);
                    if (!elem) {
                        throw new Error('No element with ID ' + elementId);
                    }

                    // Initialize map if needed
                    if (!elem.map) {
                        elem.map = L.map(elementId);
                        elem.map.addedMarkers = [];
                        L.tileLayer(tileUrl, { attribution: tileAttribution }).addTo(elem.map);
                    }

                    var map = elem.map;
                    if (map.addedMarkers.length !== markers.length) {
                        // Markers have changed, so reset
                        map.addedMarkers.forEach(marker => marker.removeFrom(map));
                        map.addedMarkers = markers.map(m => {
                            return L.marker([m.y, m.x]).bindPopup(m.description).addTo(map);
                        });

                        // Auto-fit the view
                        var markersGroup = new L.featureGroup(map.addedMarkers);
                        map.fitBounds(markersGroup.getBounds().pad(0.3));

                        // Show applicable popups. Can't do this until after the view was auto-fitted.
                        markers.forEach((marker, index) => {
                            if (marker.showPopup) {
                                map.addedMarkers[index].openPopup();
                            }
                        });
                    } else {
                        // Same number of markers, so update positions/text without changing view bounds
                        markers.forEach((marker, index) => {
                            animateMarkerMove(
                                map.addedMarkers[index].setPopupContent(marker.description),
                                marker,
                                4000);
                        });
                    }
                }
            };

            function animateMarkerMove(marker, coords, durationMs) {
                if (marker.existingAnimation) {
                    cancelAnimationFrame(marker.existingAnimation.callbackHandle);
                }

                marker.existingAnimation = {
                    startTime: new Date(),
                    durationMs: durationMs,
                    startCoords: { x: marker.getLatLng().lng, y: marker.getLatLng().lat },
                    endCoords: coords,
                    callbackHandle: window.requestAnimationFrame(() => animateMarkerMoveFrame(marker))
                };
            }

            function animateMarkerMoveFrame(marker) {
                var anim = marker.existingAnimation;
                var proportionCompleted = (new Date().valueOf() - anim.startTime.valueOf()) / anim.durationMs;
                var coordsNow = {
                    x: anim.startCoords.x + (anim.endCoords.x - anim.startCoords.x) * proportionCompleted,
                    y: anim.startCoords.y + (anim.endCoords.y - anim.startCoords.y) * proportionCompleted
                };

                marker.setLatLng([coordsNow.y, coordsNow.x]);

                if (proportionCompleted < 1) {
                    marker.existingAnimation.callbackHandle = window.requestAnimationFrame(
                        () => animateMarkerMoveFrame(marker));
                }
            }
        })();
    </script>
</body>
</html>
